#include "Common.fxh"

cbuffer cbLight
{
	matrix World;
	float Intensity;
	float3 Color;
	float3 LightPosition;
	float Radius;
};

struct VS_INPUT
{
    float4 Position : POSITION0;
};

struct PS_INPUT
{
    float4 Position : SV_POSITION;
    float4 ScreenPosition : TEXCOORD0;
};

struct PS_OUTPUT
{
	float4 DiffuseColor : SV_TARGET0;
	float4 SpecularColor : SV_TARGET1;
};

PS_INPUT VS(VS_INPUT input)
{
    PS_INPUT output;

    float4 worldPosition = mul(input.Position, World);
    output.Position = mul(worldPosition, ViewProj);
    output.ScreenPosition = output.Position;

    return output;
}

PS_OUTPUT PS(PS_INPUT input)
{
	PS_OUTPUT output;
	
	float4 position;
	float3 normal;
	float specularPower, specularIntensity;
	
	float2 screenPosition = input.ScreenPosition.xy / input.ScreenPosition.w;
	float2 texCoord = 0.5 * (float2(screenPosition.x, -screenPosition.y) + 1.0);
	
	float4 normalData = Normal.Sample(samLinear, texCoord);
	normal = 2.0 * normalData.xyz - 1.0;
	specularPower = normalData.a * 255.0;
	specularIntensity = Diffuse.Sample(samLinear, texCoord).a;
	
	float depthVal = Depth.Sample(samLinear, texCoord).r;
	
	position.xy = screenPosition.xy;
	position.z = depthVal;
	position.w = 1.0;
	position = mul(position, InverseViewProj);
	position /= position.w;
	
	float3 lightVector = LightPosition - position.xyz;
	float attenuation = saturate(1.0 - length(lightVector)/Radius);
	
	lightVector = normalize(lightVector);
	
	float NdL = max(0, dot(normal, lightVector));
	float3 diffuseLight = NdL * Color;

	float3 reflectionVector = normalize(reflect(-lightVector, normal));
	float3 directionToCamera = normalize(CameraPosition - position.xyz);
	float specularLight = specularIntensity * pow(saturate(dot(reflectionVector, directionToCamera)), specularPower);
	
	output.DiffuseColor.rgb = attenuation * Intensity * diffuseLight;
	output.SpecularColor = attenuation * Intensity * specularLight;
	
	return output;
}

technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}